#!/usr/bin/python
# Filename: mjw_server.py

import threading
import logging
import socket
import sys
import xmltodict
import json
from mjs_public import singleton
from mjs_conf import mjs_conf

mjs_conf_mgr = mjs_conf.MjsConf()

class MjwServer(singleton.Singleton, threading.Thread):
    mjw_ip = ""

    def __del__(self):
        self.serversocket.close()

    def set_mjc_server(self, mjc_server):
        self.mjc_server = mjc_server

    def run(self):
        logging.info("thread accept_thread startup")

        while True:
            logging.info("wait for mangjingw connect")
            while True:
                clientsocket, addr = self.serversocket.accept()
                ip = str(addr[0])
                logging.info("accept mangjingw %s conneting"%(ip))

                if len(self.mjw_ip) > 0:
                    self.mjwsocket.close()
                    self.mjw_ip = ""

                self.mjwsocket = clientsocket
                self.mjw_ip = ip
                break

            logging.info("ready recv mangjingw data")
            max_size = 1024 * 1024
            while True:
                # self.mjwsocket.settimeout(600)
                # logging.info("setting socket timeout = 600(s)")

                try:
                    req_json = self.mjwsocket.recv(max_size)
                    if not req_json:
                        logging.warn("mjw : %s disconnected from server" % str(self.mjw_ip))
                        self.mjwsocket.close()
                        break
                except socket.timeout:
                    logging.warn("mjw : %s timeout(120s) disconnected" % str(self.mjw_ip))
                    self.mjwsocket.close()
                    break
                except Exception as error:
                    logging.error("mjw : %s connect Exception" % str(self.mjw_ip))
                    self.mjwsocket.close()
                    break

                if len(req_json) == 0:
                    logging.error("req_json == 0")
                    continue                    

                # req_dict = xmltodict.parse(req_xml)
                logging.debug("request >>> \n%s" % req_json)

                json_list = req_json.split("}{")
                logging.info("json_list.size() = %d", len(json_list))

                if len(json_list) == 1:
                    req_dict = json.loads(req_json)
                    self.mjc_server.handle_mjw_req(req_dict)
                else:
                    i = 0
                    for one_json in json_list:
                        if i == 0:
                            new_json = one_json + "}"
                        elif i == len(json_list) - 1:
                            new_json = "{" + one_json
                        else:
                            new_json = "{" + one_json + "}"

                        logging.info("json_%d >>> \n %s" % (i + 1, new_json))
                        req_dict = json.loads(new_json)
                        self.mjc_server.handle_mjw_req(req_dict)
                        i = i + 1

    def send(self, data):
        # logging.info(data)
        if self.mjwsocket.sendall(data.encode('utf-8')) != None:
            logging.error("send data to mangjingw %s failed" % self.mjw_ip)
        else:
            logging.info("response to mangjingw >>> \n%s" % data)

    def startup(self):
        self.serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = mjs_conf_mgr.host

        try:
            self.serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.serversocket.bind((host, mjs_conf_mgr.mjw_port))
            self.serversocket.listen(mjs_conf_mgr.mjw_max)
            logging.info("mjw_server addr:%s:%d" % (socket.gethostbyname(host), mjs_conf_mgr.mjw_port))
        except Exception, e:
            logging.error("start mjw server failed: %s" % e)
            return False

        self.start()

        return True
    pass